package sevencm.wechat.common;

import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ExportExcel<T> {
	
	private static final Logger log = LoggerFactory.getLogger(ExportExcel.class);

	/**
	 * excel导出工具
	 * @param fileName 保存的文件全路径
	 * @param shellName shell名称
	 * @param headNames 标题
	 * @param fieldNames javaBean属性
	 * @param data 数据
	 */
	public void exportExcel(String fileName,String shellName, List<String> headNames,
			List<String> fieldNames, List<T> data) {
		try {
			File f = new File(this.getClass().getResource("/").getPath());
			String classPath = f.getAbsolutePath() + "/";
			File file = new File(classPath + fileName);
			HSSFWorkbook wb = null;
			if(file.exists()){
				wb = new HSSFWorkbook(new FileInputStream(file));
			}else{
				wb = new HSSFWorkbook();
			}
			HSSFSheet sheet = wb.getSheet(shellName);
			if(sheet==null){
				sheet = wb.createSheet(shellName);
			}
			sheet.setDefaultColumnWidth(15);
			HSSFCellStyle style = wb.createCellStyle();

			int rowCount = sheet.getPhysicalNumberOfRows();

			HSSFRow row = null;
			HSSFCell cell;
			if(rowCount==0){
				row = sheet.createRow(0);
				/* 设置第一栏数据-标题名称 */
				for (int i = 0, len = headNames.size(); i < len; i++) {
					String title = headNames.get(i);
					cell = row.createCell(i);
					cell.setCellValue(title);
					cell.setCellStyle(style);
				}
			}

			for (int i = rowCount, len = data.size(); i < len; i++) {
				row = sheet.createRow(i + 1); // 标题名称已经占用1行，故+1
				T t = data.get(i); // 获取javaBean
				Field[] field = t.getClass().getDeclaredFields();// 获得JavaBean全部属性
				int cellNo = 0;
				for (String fieldName : fieldNames) {
					for (int j = 0, flen = field.length; j < flen; j++) {
						if ((field[j].getName().equals(fieldName))) {
							
							String name = field[j].getName(); // 获取属性的名字
							String valName = name.substring(0, 1).toUpperCase()
									+ name.substring(1); // 将属性的首字符大写，方便构造get，set方法
							String type = field[j].getGenericType().toString();// 获取属性的类型
							Method m = t.getClass().getMethod("get" + valName);// 如果type是类类型，则前面包含"class "，后面跟类名
							switch (type) {
							case "class java.lang.String": {
								String value = (String) m.invoke(t);
								if(value!=null){
									value = value.length()>32767?value.substring(0,32767-3) + "...":value;
								}
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "class java.lang.Integer": {
								Integer value = (Integer) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "class java.lang.Short": {
								Short value = (Short) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "class java.lang.Double": {
								Double value = (Double) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "class java.lang.Boolean": {
								Boolean value = (Boolean) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "class java.util.Date": {
								Date value = (Date) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "int": {
								int value = (int) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "long": {
								long value = (long) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "float": {
								float value = (float) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							case "double": {
								double value = (double) m.invoke(t);
								row.createCell(cellNo).setCellValue(value);
							}
								break;
							default:
								String value = String.valueOf(m.invoke(t));
								row.createCell(cellNo).setCellValue(value);
							}
							cellNo++;
						}
					}
				}
			}

			FileOutputStream exportXls = new FileOutputStream( file);
			wb.write(exportXls);
			exportXls.close();
			wb.close();

		} catch (Exception e) {
			log.info(e.getMessage(),e);
			log.error(e.getMessage(),e);
		}
	}
}